<?php

class Util {

    public function config($main, $subject = null) {
        global $config;

        if($subject){
            if(isset($config[$main][$subject])){
                return $config[$main][$subject];
            }
        }
        else{
            if(isset($config[$main])){
                return $config[$main];
            }
        }

        return false;
    }


    public function pagePath($relative) {
        $sitePath = Util::config('site', 'path') ?
                    Util::config('site', 'path').'/' : '';
        return 'http://' . Util::config('site', 'server') . '/' . $sitePath .
            $relative;
    }

    public function localUrl($page, $args = null, $fragment = null) {
        $url = null;
        $extra = '';

        if($args) {
            foreach($args as $argName => $argValue) {
                $extra .= '&' . $argName . '=' . $argValue;
            }
        }

        if($fragment) {
            $extra .= '#' . $fragment;
        }

        return Util::pagePath('index.php?page='.$page.$extra);
    }

    public function redirect($url, $code = 307) {
        static $status = array(
                301 => "Moved Permanently",
                302 => "Found",
                303 => "See Other",
                307 => "Temporary Redirect");

        header('HTTP/1.1 '.$code.' '.$status[$code]);
        header("Location: $url");


        $xo = new XMLOutputter();
        $xo->XMLStart();
        $xo->dtd('a', '-//W3C//DTD XHTML 1.1//EN',
                'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd');
        $xo->element('a', array('href' => $url), $url);
        $xo->XMLEnd();
        exit;

    }

    public function encodeHTML($html_text) {
        $oUnicodeReplace = new unicode_replace_entities();
        return $oUnicodeReplace->UTF8entities($html_text);
    }

    public function decodeHTML($safe_text) {
        $html_text = html_entity_decode($safe_text, ENT_QUOTES, 'UTF-8');
        return $html_text;
    }

    public function dateSql2Print($format, $sql_date) {
        list($year, $month, $day, $hour, $min, $sec) = sscanf($sql_date,
                '%d-%d-%d %d:%d:%d');

        if( (!is_int($year)) || (!is_int($month)) || (!is_int($day)) ||
                (!is_int($hour)) || (!is_int($min)) || (!is_int($sec)) ) {
            return false;
        }

        return date($format, mktime($hour, $min, $sec, $month, $day, $year));
    }


    /* Copied from statusnet */
    
    public function randomCode($chars) {
        // 36 alphanums - lookalikes (0, O, 1, I) = 32 chars = 5 bits
        static $codechars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
        $code = '';
        for ($i = 0; $i < $chars; $i++) {
            // XXX: convert to string and back
            $num = hexdec(self::goodRand(1));
            // XXX: randomness is too precious to throw away almost
            // 40% of the bits we get!
            $code .= $codechars[$num%32];
        }
        return $code;
    }

    // returns $bytes bytes of random data as a hexadecimal string
    // "good" here is a goal and not a guarantee
    public function goodRand($bytes) {
        // XXX: use random.org...?
        if(@file_exists('/dev/urandom')) {
            return self::urandom($bytes);
        }
        else { // FIXME: this is probably not good enough
            return self::mtrand($bytes);
        }
    }

    private function urandom($bytes) {
        $h = fopen('/dev/urandom', 'rb');
        // should not block
        $src = fread($h, $bytes);
        fclose($h);
        $enc = '';
        for($i = 0; $i < $bytes; $i++) {
            $enc .= sprintf("%02x", (ord($src[$i])));
        }
        return $enc;
    }

    private function mtrand($bytes) {
        $enc = '';
        for($i = 0; $i < $bytes; $i++) {
            $enc .= sprintf("%02x", mt_rand(0, 255));
        }
        return $enc;
    }


}

//simple task: convert everything from utf-8 into an NCR[numeric character reference]
class unicode_replace_entities {
    public function UTF8entities($content="") {
        $contents = $this->unicode_string_to_array($content);
        $swap = "";
        $iCount = count($contents);
        for ($o=0;$o<$iCount;$o++) {
            $contents[$o] = $this->unicode_entity_replace($contents[$o]);
            $swap .= $contents[$o];
        }
        return mb_convert_encoding($swap,"UTF-8"); //not really necessary, but why not.
    }

    public function unicode_string_to_array( $string ) { //adjwilli
        $strlen = mb_strlen($string);
        while ($strlen) {
            $array[] = mb_substr( $string, 0, 1, "UTF-8" );
            $string = mb_substr( $string, 1, $strlen, "UTF-8" );
            $strlen = mb_strlen( $string );
        }
        return $array;
    }

    public function unicode_entity_replace($c) { //m. perez
        $h = ord($c{0});

        if( (($h >= 0x20) && ($h <= 0x2F)) ||
            (($h >= 0x3A) && ($h <= 0x40)) ||
            (($h >= 0x5B) && ($h <= 0x60)) ||
            (($h >= 0x7B) && ($h <= 0x7E)) ) {

            return '&#' . $h . ';';
        }
        else if($h <= 0x7F) {
            return $c;
        } 
        else if($h < 0xC2) {
            return $c;
        }
        
        if ($h <= 0xDF) {
            $h = ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F);
            $h = "&#" . $h . ";";
            return $h;
        } else if ($h <= 0xEF) {
            $h = ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6 | (ord($c{2}) & 0x3F);
            $h = "&#" . $h . ";";
            return $h;
        } else if ($h <= 0xF4) {
            $h = ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12 | (ord($c{2}) & 0x3F) << 6 | (ord($c{3}) & 0x3F);
            $h = "&#" . $h . ";";
            return $h;
        }
    }
} 
